package com.hemerasolutions.v2trainer.model.step.substep;

import java.util.ArrayList;
import java.util.Calendar;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;

import com.hemerasolutions.v2trainer.model.base.BaseValueHolder;
import com.hemerasolutions.v2trainer.model.exercise.Exercise;
import com.hemerasolutions.v2trainer.model.exercise.TemplateExercise;
import com.hemerasolutions.v2trainer.model.exercise.executions.Execution;
import com.hemerasolutions.v2trainer.model.exercise.intensity.IntensityExecution;
import com.hemerasolutions.v2trainer.model.exercise.intensity.IntensityModZone;
import com.hemerasolutions.v2trainer.model.exercise.intensity.IntensityTable;
import com.hemerasolutions.v2trainer.model.exercise.intensity.IntensityZone;
import com.hemerasolutions.v2trainer.model.exerciseGroup.ExerciseGroup;
import com.hemerasolutions.v2trainer.model.modality.Modality;
import com.hemerasolutions.v2trainer.model.step.Step;
import com.hemerasolutions.v2trainer.model.training.statistic.TrainingStatistic;
import com.hemerasolutions.v2trainer.model.unit.volume.VolumeFactor;
import com.hemerasolutions.v2trainer.model.unit.volume.VolumeType;
import com.hemerasolutions.v2trainer.util.Utility;

@Entity
public class ExerciseGroupStep extends BaseValueHolder {

	private static final long serialVersionUID = 1L;
	
    @Column
    private int level = 0;

    @ManyToOne
    private Modality modality;

    @ManyToOne
    private Execution execution;

    @ManyToOne
	protected VolumeType volumeType;
    
    @ManyToOne
    private IntensityModZone intensityModZone;

    @OneToOne
    private Step step;

    @ManyToOne
    private ExerciseGroup exerciseGroup;
    
    
	public ExerciseGroupStep() {
		super();
	}
	
	public ExerciseGroupStep(Step step) {
		super();
		this.step = step;
	}

	public ExerciseGroupStep (TemplateExercise te, ExerciseGroup eg, Step step){
		this.step = step;
		this.step.setName(eg.getName());
		this.modality = te.getModality();
		this.execution = te.getExecution();
		this.level = step.getTrainingStep().getLevel();
		this.volumeType = te.getVolumeType();
		this.volumeFactor = te.getVolumeFactor();
		this.intensityModZone = te.getIntensityModZone();
		this.setValue(te.getValue());

		this.step.setSteps(new ArrayList<Step>());
		
		for(Exercise exercise:eg.getExercises()){
			Step stepAux = new Step(this.step.getTrainingStep(),Step.EXERCISE_GROUPED,step);
			
			stepAux.getExerciseGroupedStep().setExercise(exercise);
			stepAux.getExerciseGroupedStep().setIntensityZone(te.getIntensityZone(exercise));

			this.step.getSteps().add(stepAux);
		}
		
	}
	
	public ExerciseGroupStep(ExerciseGroupStep other, Step parent){
		super();
		this.step = parent;
		this.value = other.value;
		this.level = parent.getTrainingStep().getLevel();
		this.execution = other.execution;
		this.volumeFactor = other.volumeFactor;
		this.volumeType = other.volumeType;
		this.intensityModZone = other.intensityModZone;
		this.modality = other.modality;
		
	}
	
	
	
	
	public IntensityZone getIntensityZone(Exercise exercise) {
		
		IntensityZone izReturn = null;
		
		for(IntensityExecution ie: exercise.getIntensityExecutions()){
			if(ie.getExecution().equals(this.intensityModZone.getIntensityModTable().getExecution())){
				for(IntensityTable it: ie.getIntensityTables()){
					if(it.getLevel() == this.getLevel()){
						for(IntensityZone iz:it.getIntensitys()){
							if(iz.getName().equals(intensityModZone.getName())){
								izReturn = iz;
							}
						}
						if(izReturn == null){
							for(IntensityZone iz:it.getIntensitys()){
								if(iz.getPosition() == intensityModZone.getPosition()){
									izReturn = iz;
								}
							}
						}
					}
				}
			}
		}
		
		return izReturn;
	}		


	public String getTranslatedExercise( String subStepDesc) {
		String desc = "";
		String restTime = Utility.timeToString(this.step.getRestInterval());
		
		desc = this.step.getRepetition() > 1 ? 	" " + this.step.getRepetition() +"x ": " " ;
		
		try{

			if(this.getVolumeFactor().isTimeBased()){
				desc += this.getIntervalToString() + " " ;		
			}else{
				desc += this.getStringValue() + " " + Utility.getText(this.getVolumeFactor().getName()) + " " ;			
			}			

			desc +=  this.getStep().getName() + " (" + subStepDesc + " )";

			if(!restTime.equals("")){
				desc += " " + "ID: " + restTime;
			}
			
			
			for(int x = 0; x < this.step.getSteps().size();x++){
				
				Step step = this.step.getSteps().get(x);
				Calendar c = null;

				if(step.getRestInterval() != null){
					c = Calendar.getInstance();
					c.setTime(step.getRestInterval());
				}
				
				
				if(step.getExerciseGroupedStep().getIntensityZone() != null){
					desc = desc + " " + step.getExerciseGroupedStep().getExercise().getName() + " " + step.getExerciseGroupedStep().getIntensityZone().getName();		
				}else{
					desc = desc + " " + step.getExerciseGroupedStep().getExercise().getName() + " " ;		
				}

				if(c != null && c.getTimeInMillis() != 0 ){
					desc = desc + " " + "ID: " + step.getIntervalToString();
				}
				
				if(x != this.step.getSteps().size() - 1){
					desc = desc + ", ";
				}
			}

			desc = desc + ") ";

		}catch (Exception e) {
			
		}
		return desc;
	}

	public String getStringValue(){
		return this.getVolumeFactor().format(this.getValue());
	}
		
	public String getIntervalToString(){
		return Utility.timeToString(this.getDateValue());
	}
		
	@Override
	public Integer getId() {
		return this.id;
	}

	@Override
	public void setId(Integer id) {
		this.id = id;
	}	
	
	public int getLevel() {
		return level;
	}

	public void setLevel(int level) {
		this.level = level;
	}

	public Execution getExecution() {
		return execution;
	}

	public void setExecution(Execution execution) {
		this.execution = execution;
	}

	public VolumeFactor getVolumeFactor() {
		return volumeFactor;
	}

	public void setVolumeFactor(VolumeFactor volumeFactor) {
		this.volumeFactor = volumeFactor;
	}

	public VolumeType getVolumeType() {
		return volumeType;
	}

	public void setVolumeType(VolumeType volumeType) {
		this.volumeType = volumeType;
	}

	public Modality getModality() {
		return modality;
	}

	public void setModality(Modality modality) {
		this.modality = modality;
	}

	public IntensityModZone getIntensityModZone() {
		return intensityModZone;
	}

	public void setIntensityModZone(IntensityModZone intensityModZone) {
		this.intensityModZone = intensityModZone;
	}

	public Step getStep() {
		return step;
	}


	public void setStep(Step step) {
		this.step = step;
	}

	public ExerciseGroup getExerciseGroup() {
		return exerciseGroup;
	}

	public void setExerciseGroup(ExerciseGroup exerciseGroup) {
		this.exerciseGroup = exerciseGroup;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result + ((step == null) ? 0 : step.hashCode());
		return result;
	}


	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ExerciseGroupStep other = (ExerciseGroupStep) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		if (step == null) {
			if (other.step != null)
				return false;
		} else if (!step.equals(other.step))
			return false;
		return true;
	}


	@Override
	public String toString() {
		return "ExerciseGroupStep [id=" + id + ", step=" + step + "]";
	}

	public TrainingStatistic calcStatistic() {
		
		TrainingStatistic ts = new TrainingStatistic(this.step.getTrainingStep(),TrainingStatistic.GROUP_STATISTIC);
		
		ts.setRestTime(Utility.longToDate(this.calculateRestTime()));
		
		return ts;
	}

	
	public long calculateRestTime(){
		return Utility.dateToLong(step.getRestInterval());
	}	
	
	public Double getRealValue() {
		return this.value;
	}

	public void setRealValue(double value) {
		this.value = value;
	}

	
	//	public List<TrainingStatistic> collectStatistics() {
//		
//		List<TrainingStatistic> statistics = new ArrayList<TrainingStatistic>();
//		
//		for(Step stepAux: this.step.getSteps()){
//			TrainingStatistic statistic = new TrainingStatistic(TrainingStatistic.EXERCISE_STATISTIC);
//			statistic.setExercise(stepAux.getExerciseGroupedStep().getExercise());
//			statistic.setVolumeFactor(volumeFactor);
//			statistic.setVolumeType(volumeType);
//			statistic.setIntensityZone(this.getIntensityZone(stepAux.getExerciseGroupedStep().getExercise()));
//			statistic.setExecution(execution);
//			statistic.setValue(this.getValue());
//			statistic.setExpentTime(this.calculateExpentTime());
//			this.calculateArbitraryUnit();
//			
//			statistics.add(statistic);
//			
//		}
//
//		return statistics;
//
//	}
//
//	private int calculateArbitraryUnit() {
//		int totalAu = 0;
//		int au = 0;
//			
//		for(Step stepAux: this.step.getSteps()){
//			au = 0;
//			IntensityZone intensityZone = this.getIntensityZone(stepAux.getExerciseGroupedStep().getExercise());
//			if(intensityZone != null){
//				if( intensityZone.getLowRpe() != null && intensityZone.getHighRpe() != null	){
//					au = au + (int) (intensityZone.getUaFactor() * (intensityZone.getLowRpe().getValue() + intensityZone.getHighRpe().getValue())/ 2);
//				}
//
//				if(this.volumeType.getName().equals("V_REPETITION")){
//					au = au * (int)this.getValue();
//				}
//
//				au = au * this.getStep().getRepetition();			
//				totalAu = totalAu + au;
//			}
//		}
//		
//		return totalAu;
//	}
//
//	private double calculateExpentTime() {
//    	double time = 0;
//    	double totalTime = 0;
//    	
//		for(Step stepAux: this.step.getSteps()){
//			IntensityZone intensityZone = this.getIntensityZone(stepAux.getExerciseGroupedStep().getExercise());
//
//			time = 0;
//			
//			if(intensityZone != null){
//	    		if(modality.getTrainingType().getIntensityVolume().getName().equals("V_TIME")){
//	    			Calendar calendar = Calendar.getInstance();
//	    			if(intensityZone.getConcentricTime() != null){
//		    			calendar.setTime(intensityZone.getConcentricTime());
//		    			time = calendar.getTimeInMillis();
//	    			}
//	    			if(intensityZone.getEccentricTime() != null){
//		    			calendar.setTime(intensityZone.getEccentricTime());
//		    			time = time + calendar.getTimeInMillis();
//	    			}
//	    		}else if (modality.getTrainingType().getIntensityVolume().getName().equals("V_DISTANCE")){
//	    			if(this.volumeType.getName().equals("V_TIME")){
//	    				time = this.value;
//	    			}else if(this.volumeType.getName().equals("V_DISTANCE")){
//	    				if(intensityZone.getRealAverageSpeed() != 0){
//	        				time = this.value / intensityZone.getRealAverageSpeed();
//	    				}
//	    			}
//	    		}else{
//	    			if(this.volumeType.getName().equals("V_TIME")){
//	    				time = this.value;
//	    			}
//	    		}
//	    	}
//
//			time = time * step.getRepetition();
//
//	    	
//	    	if(volumeType.getName().equals("V_REPETITION")){
//				time = time * this.value;
//	    	}
//	    	totalTime = totalTime + time;
//		}	
//
//    	return totalTime;
//	}
//
	
	
}
